﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.ServiceModel;
using System.ServiceModel.Web;
using Earthwatchers.Data;
using Earthwatchers.Models;
using Earthwatchers.Services.Security;

namespace Earthwatchers.Services.Resources
{
    [ServiceContract]
    public class LandResource
    {
        private readonly ILandRepository landRepository;

        public LandResource(ILandRepository landRepository)
        {
            this.landRepository = landRepository;
        }

        [WebGet(UriTemplate = "")]
        public HttpResponseMessage<List<Land>> GetAll(HttpRequestMessage request)
        {
            var landCollection = landRepository.GetAll();
            foreach (var land in landCollection)
            {
                LandLinks.AddLinks(land, request);
            }
            return new HttpResponseMessage<List<Land>>(landCollection) { StatusCode = HttpStatusCode.OK };
        }

        [WebGet(UriTemplate = "{id}")]
        public HttpResponseMessage<Land> Get(int id, HttpRequestMessage request)
        {
            var land = landRepository.GetLand(id);
            if (land == null)
            {
                return new HttpResponseMessage<Land>(HttpStatusCode.NotFound);
            }

            LandLinks.AddLinks(land,request);

            return new HttpResponseMessage<Land>(land) { StatusCode = HttpStatusCode.OK };
        }
                        
        [WebGet(UriTemplate = "/intersect={wkt}")]
        public HttpResponseMessage<List<Land>> GetLandByWkt(string wkt, HttpRequestMessage request)
        {
            if (!string.IsNullOrEmpty(wkt))
            {
                // todo: check if wkt is valid...
                // we can use SqlGeometry but there are some issues on Azure with that assembly
                // other option is do a spatial database query for this

                var landCollection = landRepository.GetLandByIntersect(wkt);
                foreach (var land in landCollection)
                {
                    LandLinks.AddLinks(land, request);
                }
                return new HttpResponseMessage<List<Land>>(landCollection) { StatusCode = HttpStatusCode.OK };
            }
            return new HttpResponseMessage<List<Land>>(null) { StatusCode = HttpStatusCode.PartialContent };
        }

        [WebGet(UriTemplate = "/status={landStatus}")]
        public HttpResponseMessage<List<Land>> GetAllByStatus(LandStatus landStatus, HttpRequestMessage request)
        {
            var landCollection = landRepository.GetLandByStatus(landStatus);
            foreach (var land in landCollection)
            {
                LandLinks.AddLinks(land, request);
            }
            return new HttpResponseMessage<List<Land>>(landCollection) { StatusCode = HttpStatusCode.OK };
        }

        [WebGet(UriTemplate = "/earthwatcher={earthwatcher}")]
        public HttpResponseMessage<Land> GetLandByEarthwatcherName(string earthwatcherName, HttpRequestMessage request)
        {
            if(!String.IsNullOrEmpty(earthwatcherName))
            {
                var land = landRepository.GetLandByEarthwatcherName(earthwatcherName);
                if (land != null)
                {
                    return new HttpResponseMessage<Land>(land) {StatusCode = HttpStatusCode.OK};
                }
                return new HttpResponseMessage<Land>(null) { StatusCode = HttpStatusCode.NotFound};
            }
            return new HttpResponseMessage<Land>(null) { StatusCode = HttpStatusCode.BadRequest};
        }


        [BasicHttpAuthorization(Role.Earthwatcher)]
        [WebInvoke(UriTemplate = "{id}/updatestatus", Method = "PUT")]
        public HttpResponseMessage UpdateStatusLand(int id, Land land, HttpRequestMessage<Land> request)
        {
            if (landRepository.GetLand(id) != null)
            {
                landRepository.UpdateLandStatus(id, land.LandStatus);
                return new HttpResponseMessage(){StatusCode = HttpStatusCode.OK};
            }
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

        [BasicHttpAuthorization(Role.Earthwatcher)]
        [WebInvoke(UriTemplate = "{id}/confirm", Method = "PUT")]
        public HttpResponseMessage Confirm(Earthwatcher earthwatcher, int id, HttpRequestMessage<Earthwatcher> request)
        {
            if (landRepository.GetLand(id) != null)
            {
                landRepository.ConfirmLand(id, earthwatcher);
                return new HttpResponseMessage() { StatusCode = HttpStatusCode.OK };
            }
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

        [BasicHttpAuthorization(Role.Earthwatcher)]
        [WebInvoke(UriTemplate = "{id}/deconfirm", Method = "PUT")]
        public HttpResponseMessage Deconfirm(Earthwatcher earthwatcher, int id, HttpRequestMessage<Earthwatcher> request)
        {
            if (landRepository.GetLand(id) != null)
            {
                landRepository.DeconfirmLand(id, earthwatcher);
                return new HttpResponseMessage() { StatusCode = HttpStatusCode.OK };
            }
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }
}